<?php

namespace App\Services\Applet\Cart;

use App\Exceptions\CartException;
use App\Exceptions\OtherException;
use App\Exceptions\ShopException;
use App\Helpers\MvcHelper;
use App\Models\Applet\Cart\CartModel;
use App\Models\Applet\Shop\ShopGoodsModel;
use App\Models\BaseModel;
use Exception;

class CartService extends BaseCartService
{

    /**
     * 购物车列表
     *
     * @param array $params
     * @return array[]
     * @throws Exception
     */
    public function list(array $params): array
    {
        // 查询购物车总条数
        $total = $this->getCartModel()->total($params['type']);
        // 查询购物车表
        $cartList = $this->getCartModel()->list($params['type'], [
            'id', 'type', 'goods_id', 'quantity'
        ]);

        $goodsIds = array_column($cartList, 'goods_id');
        $goodsListMap = $this->_getGoodsList($params['type'], $goodsIds);

        $list = [];
        foreach ($cartList as $item) {

            $goodsInfo = $goodsListMap[$item['goods_id']] ?? '';

            $status = 10; // 正常
            if (!empty($goodsInfo) && ($goodsInfo['status'] == ShopGoodsModel::STATUS_NO || $goodsInfo['deleted'] == BaseModel::DELETED_YES)) {
                $status = 20; // 失效
            }

            // 计算预计出栏时间
            $endTime = '';
            if (!empty($goodsInfo) && $params['type'] == 10) {
                $endTime = date('Y-m-d', strtotime($goodsInfo['start_time']) + $goodsInfo['cycle'] * 7 * 24 * 3600);
            }

            $list[] = [
                'id' => $item['id'],
                'goodsId' => $goodsInfo['id'] ?? 0,
                'name' => $goodsInfo['name'] ?? '',
                'coverImg' => $goodsInfo['cover_img'] ?? '',
                'price' => ($goodsInfo['price'] ?? 0) / 100,
                'quantity' => $item['quantity'],
                'endTime' => $endTime,
                'weight' => ($goodsInfo['weight'] ?? 0) / 1000,
                'shippingFee' => ($goodsInfo['shipping_fee'] ?? 0) / 100,
                'status' => $status
            ];
        }
        return [
            'total' => $total,
            'list' => $list,
        ];
    }

    /**
     * 购物车总数量
     * @return void
     * @throws Exception
     */
    public function totalQuantity(array $params): array
    {
        $total = $this->getCartModel()->total($params['type']);
        return [
            'total' => $total,
        ];
    }

    /**
     * 添加购物车
     *
     * @return void
     * @throws Exception
     */
    public function create(array $params)
    {
        // 添加操作锁
        if (!$this->lockOperate('cartUserId', MvcHelper::getLoginUserId())) {
            throw new ShopException('操作频繁，请稍后重试', ShopException::CODE_6001);
        }

        try {
            // 查询购物车商品
            $cartData = $this->getCartModel()->getItemByGoodsIdAndType($params['goodsId'], $params['type'], [
                'id', 'quantity'
            ]);

            // 查询商品
            $goodsInfo = [];
            switch ($params['type']) {
                case CartModel::TYPE_SPONSOR:
                    $goodsInfo = $this->getSponsorGoodsModel()->getItemById($params['goodsId'], [
                        'id', 'quantity'
                    ]);
                    break;
                case CartModel::TYPE_SHOP:
                    $goodsInfo = $this->getShopGoodsModel()->getItemById($params['goodsId'], [
                        'id', 'quantity'
                    ]);
                    break;
            }

            if (empty($goodsInfo)) {
                throw new CartException('商品不存在', CartException::CODE_1001);
            }

            if ($cartData) {
                $updateCartData = [
                    'quantity' => $cartData['quantity'] + $params['quantity'],
                ];
                $this->getCartModel()->updateItemById($cartData['id'], $updateCartData);
            } else {
                $createCart = [
                    'user_id' => MvcHelper::getLoginUserId(),
                    'goods_id' => $params['goodsId'],
                    'type' => $params['type'],
                    'quantity' => $params['quantity'],
                ];
                // 添加购物车
                $this->getCartModel()->addItem($createCart);
            }
            $this->unlockOperate('cartUserId', MvcHelper::getLoginUserId());
        } catch (Exception $exception) {
            $this->unlockOperate('cartUserId', MvcHelper::getLoginUserId());
            throw $exception;
        }
    }

    /**
     * 更新购物车
     * @return void
     * @throws Exception
     */
    public function update(array $params)
    {
        // 查询购物车数据
        $cartData = $this->getCartModel()->getItemById($params['id']);
        if (empty($cartData)) {
            throw new OtherException(OtherException::CODE_1000, '购物车数据不存在');
        }

        $updateCartData = [
            'quantity' => $params['quantity'],
        ];

        $this->getCartModel()->updateItemById($cartData['id'], $updateCartData);
    }

    /**
     * 删除购物车数据
     * @return void
     * @throws Exception
     */
    public function delete(array $params)
    {
        // 查询购物车数据
        $cartData = $this->getCartModel()->getItemById($params['id']);
        if (empty($cartData)) {
            throw new OtherException(OtherException::CODE_1000, '购物车数据不存在');
        }

        // 删除购物车数据
        $this->getCartModel()->deleteItemById($params['id']);
    }

    /**
     * @param int $type
     * @param array $goodsIds
     * @return array
     * @throws Exception
     */
    public function _getGoodsList(int $type, array $goodsIds): array
    {
        if ($type == 10) {
            // 查询商品信息
            $goodsList = $this->getSponsorGoodsModel()->getItemsByIdAndDeletedAll($goodsIds, [
                'id', 'name', 'cover_img', 'price', 'start_time', 'cycle', 'status', 'deleted'
            ]);
        } else {
            // 查询商品信息
            $goodsList = $this->getShopGoodsModel()->getItemsByIdAndDeletedAll($goodsIds, [
                'id', 'name', 'cover_img', 'price', 'weight', 'status', 'shipping_fee', 'deleted'
            ]);
        }
        return array_column($goodsList, null, 'id');
    }
}
